#!/bin/bash

# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"

: "${SERVER_PROPERTIES:=/data/server.properties}"

# FUNCTIONS
function setServerPropValue {
  local prop=$1
  local value=$2
  # normalize booleans
  case ${value^^} in
    TRUE|FALSE)
      value=${value,,} ;;
  esac
  if grep "${prop}" "$SERVER_PROPERTIES" > /dev/null; then
    log "Setting ${prop} to '${value}' in ${SERVER_PROPERTIES}"
    sed -i "/^${prop}\s*=/ c ${prop}=${value//\\/\\\\}" "$SERVER_PROPERTIES"
  else
    log "Adding ${prop} with '${value}' in ${SERVER_PROPERTIES}"
    echo "${prop}=${value}" >> "$SERVER_PROPERTIES"
  fi
}

function setServerProp {
  local prop=$1
  local varName=$2

  if [ -v $varName ]; then
    setServerPropValue "$prop" "${!varName}"
  fi
}

function customizeServerProps {
  # Whitelist processing
  if [ -n "$WHITELIST" ] || [ -n "$WHITELIST_FILE" ] || isTrue "${ENABLE_WHITELIST:-false}"; then
    log "Enabling whitelist functionality"
    setServerPropValue "white-list" "true"
  else
    log "Disabling whitelist functionality"
    setServerPropValue "white-list" "false"
  fi
  setServerProp "enforce-whitelist" ENFORCE_WHITELIST
  if [[ $(grep "enforce-whitelist" $SERVER_PROPERTIES) != *true ]]; then
    log "WARNING: whitelist enabled but not enforced. Set ENFORCE_WHITELIST=TRUE or update 'enforce-whitelist' in server.properties to enforce the whitelist."
  fi

  # If not provided, generate a reasonable default message-of-the-day,
  # which shows up in the server listing in the client
  if ! [ -v MOTD ]; then
    # snapshot is the odd case where we have to look at version to identify that label
    if [[ ${ORIGINAL_TYPE} == "VANILLA" && ${VERSION} == "SNAPSHOT" ]]; then
      label=SNAPSHOT
    else
      label=${ORIGINAL_TYPE}
    fi

    # Convert label to title-case
    label=${label,,}
    label=${label^}
    MOTD="A ${label} Minecraft Server powered by Docker"
  fi

  # normalize MOTD
  if [[ ${TYPE^^} = LIMBO ]]; then
    if [[ $MOTD ]] && ! [[ $MOTD =~ ^{ ]]; then
      MOTD="{\"text\":\"${MOTD}\"}"
    fi
  fi

  setServerProp "server-name" SERVER_NAME
  setServerProp "server-ip" SERVER_IP
  setServerProp "server-port" SERVER_PORT
  setServerProp "allow-nether" ALLOW_NETHER
  setServerProp "announce-player-achievements" ANNOUNCE_PLAYER_ACHIEVEMENTS
  setServerProp "enable-command-block" ENABLE_COMMAND_BLOCK
  setServerProp "spawn-animals" SPAWN_ANIMALS
  setServerProp "spawn-monsters" SPAWN_MONSTERS
  setServerProp "spawn-npcs" SPAWN_NPCS
  setServerProp "spawn-protection" SPAWN_PROTECTION
  setServerProp "generate-structures" GENERATE_STRUCTURES
  setServerProp "view-distance" VIEW_DISTANCE
  setServerProp "hardcore" HARDCORE
  setServerProp "snooper-enabled" SNOOPER_ENABLED
  setServerProp "max-build-height" MAX_BUILD_HEIGHT
  setServerProp "force-gamemode" FORCE_GAMEMODE
  setServerProp "max-tick-time" MAX_TICK_TIME
  setServerProp "enable-query" ENABLE_QUERY
  setServerProp "query.port" QUERY_PORT
  setServerProp "enable-rcon" ENABLE_RCON
  setServerProp "rcon.password" RCON_PASSWORD
  setServerProp "rcon.port" RCON_PORT
  setServerProp "max-players" MAX_PLAYERS
  setServerProp "max-world-size" MAX_WORLD_SIZE
  setServerProp "level-name" LEVEL
  setServerProp "level-seed" SEED
  setServerProp "pvp" PVP
  setServerProp "generator-settings" GENERATOR_SETTINGS
  setServerProp "online-mode" ONLINE_MODE
  setServerProp "allow-flight" ALLOW_FLIGHT
  setServerProp "resource-pack" RESOURCE_PACK
  setServerProp "resource-pack-sha1" RESOURCE_PACK_SHA1
  setServerProp "require-resource-pack" RESOURCE_PACK_ENFORCE
  setServerProp "player-idle-timeout" PLAYER_IDLE_TIMEOUT
  setServerProp "broadcast-console-to-ops" BROADCAST_CONSOLE_TO_OPS
  setServerProp "broadcast-rcon-to-ops" BROADCAST_RCON_TO_OPS
  setServerProp "enable-jmx-monitoring" ENABLE_JMX
  setServerProp "sync-chunk-writes" SYNC_CHUNK_WRITES
  setServerProp "enable-status" ENABLE_STATUS
  setServerProp "entity-broadcast-range-percentage" ENTITY_BROADCAST_RANGE_PERCENTAGE
  setServerProp "function-permission-level" FUNCTION_PERMISSION_LEVEL
  setServerProp "network-compression-threshold" NETWORK_COMPRESSION_THRESHOLD
  setServerProp "op-permission-level" OP_PERMISSION_LEVEL
  setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS
  setServerProp "use-native-transport" USE_NATIVE_TRANSPORT
  setServerProp "simulation-distance" SIMULATION_DISTANCE
  setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)"
  [[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}"

  if [ -n "$DIFFICULTY" ]; then
    case ${DIFFICULTY,,} in
      peaceful|0)
        if versionLessThan 1.13; then
          DIFFICULTY=0
        else
          DIFFICULTY=peaceful
        fi
        ;;
      easy|1)
        if versionLessThan 1.13; then
          DIFFICULTY=1
        else
          DIFFICULTY=easy
        fi
        ;;
      normal|2)
        if versionLessThan 1.13; then
          DIFFICULTY=2
        else
          DIFFICULTY=normal
        fi
        ;;
      hard|3)
        if versionLessThan 1.13; then
          DIFFICULTY=3
        else
          DIFFICULTY=hard
        fi
        ;;
      *)
        log "DIFFICULTY must be peaceful, easy, normal, or hard."
        exit 1
        ;;
    esac
    setServerPropValue "difficulty" "$DIFFICULTY"
  fi

  if [ -n "$MODE" ]; then
    log "Setting mode"
    case ${MODE,,} in
      su*|0)
        if versionLessThan 1.13; then
          MODE=0
        else
          MODE=survival
        fi
        ;;
      c*|1)
        if versionLessThan 1.13; then
          MODE=1
        else
          MODE=creative
        fi
        ;;
      a*|2)
        if versionLessThan 1.13; then
          MODE=2
        else
          MODE=adventure
        fi
        ;;
      sp*|3)
        if versionLessThan 1.13; then
          MODE=3
        else
          MODE=spectator
        fi
        ;;
      *)
        log "ERROR: Invalid game mode: $MODE"
        exit 1
        ;;
    esac
    setServerPropValue "gamemode" "$MODE"
  fi
}

# Deploy server.properties file
if [[ ${TYPE} == "CURSEFORGE" ]]; then
  export SERVER_PROPERTIES="${FTB_DIR}/server.properties"
  log "detected FTB, changing properties path to ${SERVER_PROPERTIES}"
fi

if ! isTrue "${SKIP_SERVER_PROPERTIES:-false}"; then
  if [ ! -e "$SERVER_PROPERTIES" ]; then
    log "Creating server.properties in ${SERVER_PROPERTIES}"
    cp /tmp/server.properties "$SERVER_PROPERTIES"
    customizeServerProps
  elif [ -n "${OVERRIDE_SERVER_PROPERTIES}" ]; then
      case ${OVERRIDE_SERVER_PROPERTIES^^} in
        TRUE|1)
          customizeServerProps
          ;;
        *)
          log "server.properties already created, skipping"
          ;;
      esac
  else
    log "server.properties already created, skipping"
  fi
else
  log "Skipping setup of server.properties"
fi

if isTrue "${ENABLE_AUTOPAUSE}"; then
  current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' )
  if (( current_max_tick > 0 && current_max_tick < 86400000 )); then
    log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled."
    log "Warning (cont): Autopause functionality resuming the process might trigger the Watchdog and restart the server completely."
    log "Warning (cont): Set the max-tick-time property to a high value (or disable the Watchdog with value -1 for versions 1.8.1+)."
  fi
fi

if isDebugging && [ -f "${SERVER_PROPERTIES}" ]; then
  log "DEBUG Dumping server.properties"
  cat "${SERVER_PROPERTIES}"
fi

exec "${SCRIPTS:-/}start-setupEnvVariables" "$@"
